package com.enlorenz.common.excel;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.Region;

import com.enlorenz.common.entity.PairEntity;
import com.enlorenz.common.excel.anno.ExportParam;
import com.enlorenz.common.util.DataDetUtils;
import com.enlorenz.common.util.StringUtils;
import com.enlorenz.core.enu.EnumUtils;

/**
 * xls文件导出
 * @author Karma
 */
public class DataExporter4Xls<T> extends AbstractDataExporter<T>{
	//列宽加成
	public static final int COL_WIDTH_PLUS=256;
	//sheet名称
	private String sheetName="default";
	//是否自动适应列宽
	private SizeColumnModel sizeColumnModel=SizeColumnModel.SIZE_NO_PARAM;
	private HSSFWorkbook workbook;
	private HSSFSheet sheet;
	private HSSFRow row;
	//默认的编码
	private String defaultEncoding="gbk";
	//列最大的长度
	private Integer [] colsMaxLength;
	
	public DataExporter4Xls(Class<T> dataClass){
		super(dataClass);
	}
	
	public DataExporter4Xls(){
	}
	
	public void setSizeColumnModel(SizeColumnModel sizeColumnModel) {
		this.sizeColumnModel = sizeColumnModel;
	}

	public void setSheetName(String sheetName) {
		this.sheetName = sheetName;
	}
	
	private List<Object> headList=new ArrayList<Object>();
	private List<Object> tailList=new ArrayList<Object>();
	/**
	 * 加入标题
	 * @param text
	 */
	public void addHead(String text,PoiStyleSetter dataValue){
		headList.add(new PairEntity(dataValue, text));
	}
	
	public void addHead(CustomRowData customRowData){
		headList.add(customRowData);
	}
	
	public void addTail(CustomRowData customRowData){
		tailList.add(customRowData);
	}
	
	/**
	 * 加入标题
	 * @param text
	 */
	public void addHead(String text){
		addHead(text, null);
	}
	
	/**
	 * 加入结尾
	 * @param text
	 */
	public void addTail(String text){
		addTail(text, null);
	}
	
	/**
	 * 加入结尾
	 * @param text
	 */
	public void addTail(String text,PoiStyleSetter dataValue){
		tailList.add(new PairEntity(dataValue, text));
	}
	
    /**
	 * 在导出之前做的事情
	 * @param outputStream
	 */
	protected void beforeExport(OutputStream outputStream){
		  // 创建Excel文档
        workbook = new HSSFWorkbook();
        // sheet 对应一个工作页
        sheet = workbook.createSheet(sheetName);
        
        //创建扩展行
        createExtendRows(headList);
        
        //headRow = sheet.createRow(generateRowCount()); 

		colsMaxLength=new Integer[propList.size()];
	}
	
	
	protected void createExtendRows(List<Object> dataList) {
		if(!DataDetUtils.isCollectionEmpty(dataList)){
        	for(Object object:dataList){
        		if(object instanceof PairEntity){
        			doPairEntity(object);
        		}else{
        			doCustomRowData(object);
        		}
        	}
        }
	}

	private void doCustomRowData(Object object) {
		CustomRowData customRowData=(CustomRowData)object;
		int currentRowIndex=0;
		int rowCount=generateRowCount();
		row = sheet.createRow(rowCount);
		for(CustomCellData cellData:customRowData.getCellList()){
			HSSFCellStyle style=workbook.createCellStyle();
			HSSFFont font=workbook.createFont();
			HSSFDataFormat format = workbook.createDataFormat();  
			style.setFont(font);
			
			
			Object value=cellData.getValue();
			HSSFCell cell = row.createCell(currentRowIndex);
			PoiStyleSetter setter=(PoiStyleSetter)cellData.getSetter();
			if(null!=setter){
				setter.setHSSFCellStyle(format,cell,style,font);
			}
			
			short rowTo=(short)(currentRowIndex+cellData.getColspan()-1);
		    sheet.addMergedRegion(new Region(rowCount,(short)currentRowIndex,
		    		rowCount,rowTo));
		    currentRowIndex=rowTo+1;
		    
		    cell.setCellStyle(style);
			if(null!=value){
				cell.setCellValue(value.toString());
			}else{
				cell.setCellValue("");
			}
		}
	}

	private void doPairEntity(Object object) {
		PairEntity pairEntity=(PairEntity)object;
		HSSFCellStyle style=workbook.createCellStyle();
		HSSFFont font=workbook.createFont();
		HSSFDataFormat format = workbook.createDataFormat();  
		style.setFont(font);
		
		
		String value=(String)pairEntity.getValue();
		int rowCount=generateRowCount();
		row = sheet.createRow(rowCount);
		HSSFCell cell = row.createCell(0);
		
		sheet.addMergedRegion(new Region(rowCount,(short)0,rowCount,(short)(propList.size()-1)));
		
		
		PoiStyleSetter setter=(PoiStyleSetter)pairEntity.getKey();
		if(null!=setter){
			setter.setHSSFCellStyle(format,cell,style,font);
		}
		cell.setCellStyle(style);
		cell.setCellValue(value);
	}
	

	
	@Override
	protected void doDataValue(int rowIndex, int rowSize, int colIndex,
			int colSize, String dataValue) {
		int curLen=StringUtils.getBytes(dataValue, defaultEncoding).length;
		int colsMaxLen=colsMaxLength[colIndex];
		if(curLen>colsMaxLen){
			colsMaxLength[colIndex]=curLen;
		}
		
        // 在一行内循环
        HSSFCell cell = row.createCell(colIndex);
        cell.setCellValue(dataValue);
	}
	
	private HSSFRow headRow;
	
	/**
	 * 初始化表头
	 */
	protected void initPropHead(int headIndex){
		headRow = sheet.createRow(headIndex);
	}
	
	/**
	 * 初始化行数据
	 */
	protected void initRowData(int dataIndex){
		row = sheet.createRow(dataIndex);
	}
	
	@Override
	protected void doHeadValue(int colIndex, int colSize,DataHeadParam dataHeadParam) {
		if(showTitle){
			HSSFCell headCell= headRow.createCell(colIndex);
	    	headCell.setCellValue(new HSSFRichTextString(dataHeadParam.getProperty().name()));
			colsMaxLength[colIndex]=StringUtils.getBytes(dataHeadParam.getProperty().name(), 
								defaultEncoding).length;
		}
		
    	ExportParam cp=dataHeadParam.getColumnParam();
    	if(null!=cp && AbstractDataExporter.DEFAULT_COL_WIDTH!=cp.colWidth()){
    		setColumWidth((short)colIndex, 
    				(short)cp.colWidth()*COL_WIDTH_PLUS+COL_WIDTH_PLUS/2);
    	}
	}
	
	protected boolean isShowTableTitle(){
		return true;
	}
	
  /**
	 * 在导出之后做的事情
	 * @param outputStream
	 */
	protected void afterExport(OutputStream outputStream){
		if(!EnumUtils.isEq(sizeColumnModel, SizeColumnModel.SIZE_NONE)){
			for(int i=0;i<propList.size();i++){
				if(EnumUtils.isEq(sizeColumnModel, SizeColumnModel.SIZE_NO_PARAM)){
					String headKey=propList.get(i);
					DataHeadParam dataHeadParam=elementIterator.getHeadParam(headKey);
					ExportParam cp=dataHeadParam.getColumnParam();
			    	if(null ==cp || AbstractDataExporter.DEFAULT_COL_WIDTH == cp.colWidth()){
			    		//System.out.println(i+":"+colsMaxLength[i]);
			    		setColumWidth(i,colsMaxLength[i]*COL_WIDTH_PLUS+COL_WIDTH_PLUS/2); //调整第一列宽度 
			    	}
				}else{
					//System.out.println(i+":"+colsMaxLength[i]);
					setColumWidth(i,colsMaxLength[i]*COL_WIDTH_PLUS+COL_WIDTH_PLUS/2); //调整第一列宽度 
				}
			}
		}
		
		createExtendRows(tailList);
	}
	
	/**
	 * 设置列宽
	 * @param index
	 * @param witdh
	 */
	protected void setColumWidth(int index,int witdh){
		sheet.setColumnWidth(index,witdh);
	}
	
	@Override
	protected void writeOutputStream(OutputStream outputStream) {
		try {
			workbook.write(outputStream);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	

	public String getDefaultEncoding() {
		return defaultEncoding;
	}

	public void setDefaultEncoding(String defaultEncoding) {
		this.defaultEncoding = defaultEncoding;
	}
}
